//////////////////////////////////////////////////////////////////////////////////////////////////////
// 项目名   : Asynchronous
// 文件名   : CSP.h
// 作者     : Aiye
// 日期     : 2025/10/3 07:22
// 邮箱     : 2878548868@qq.com
// 摘要     : 介绍CSP设计模式
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef ASYNCHRONOUS_CSP_H
#define ASYNCHRONOUS_CSP_H
#include <condition_variable>
#include <mutex>
#include <queue>

/**
 * @brief CSP设计模式
 * @tparam T 通道传输的数据类型
 */
template<typename T>
class CSP
{
public:
    /**
     * @brief 向通道发送信息，将数据放到消息队列中，通知等待接受数据的线程
     * @param data 要发送的数据
     */
    void send(T data)
    {
        {
            std::lock_guard lock{_mtx};
            if (_bClose)
            {
                throw std::runtime_error("Send on closed channel");
            }
            _qeData.push(std::move(data));
        }
        _cv.notify_one();
    }

    /**
     * @brief 从通道中接收数据
     * @param data 储存接受到的数据
     * @return 返回是否成功接受到数据
     */
    bool revc(T& data)
    {
        std::unique_lock lock{_mtx};
        _cv.wait(lock , [&]
        {
           return !_qeData.empty() || _bClose;
        });

        if (_qeData.empty())
        {
            return false;
        }

        data = std::move(_qeData.front());
        _qeData.pop();
        return true;
    }

    /**
     * @brief 关闭通道
     */
    void close()
    {
        std::lock_guard lock{_mtx};
        _bClose = true;
    }

private:
    std::queue<T> _qeData{};        // 数据队列，用于储存待处理的数据
    std::mutex _mtx{};              // 互斥锁，保护数据队列的访问
    std::condition_variable _cv;    // 条件变量。用于子在数据队列为空是阻塞线程
    bool _bClose{false};            // 标志位，表示通道是否一关闭
};

#endif //ASYNCHRONOUS_CSP_H